home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
pcr
/
pcr4_4.lha
/
DIST
/
gc
/
GCenum_objs.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-06-06
|
3KB
|
103 lines
#include <xr/Threads.h>
#include <xr/GCPrivate.h>
#include <xr/ThreadsSchedCtl.h>
#include <xr/GCenum_objs.h>
/* Priorirty of "world stopped" collection */
static XR_Pri gcExclusivePriority = XR_PRI_SYS_EXCLUSIVE;
typedef struct CallBackInfoRep {
callback_fn my_fn;
XR_Pointer my_client_data;
bool got_proper_callback;
} * CallBackInfo;
void XR_EnumObjsInner();
static void callback(cbi, info)
CallBackInfo cbi;
GC_Info info;
{
if (!(info -> gci_full_collection)) return;
if (cbi -> got_proper_callback) return;
XR_EnumObjsInner(cbi -> my_fn, cbi -> my_client_data);
cbi -> got_proper_callback = TRUE;
}
/* Call fn for each marked object in the heap. */
void XR_EnumObjsInner(fn, client_data)
callback_fn fn;
XR_Pointer client_data;
{
register struct hblk *hbp; /* ptr to current heap block */
register int word_no; /* Number of word in block */
register int mb; /* mark bit of current object */
register word *p; /* pointer to current word in block */
word *plim;
int sz; /* size of objects in current block */
struct hblk **nexthbp; /* ptr to ptr to current heap block */
bool is_atomic;
hbp = (struct hblk *) GC_heapstart;
for (; ((char *)hbp) < GC_heaplim; hbp++) if (is_hblk(hbp)) {
sz = hb_sz(hbp);
if (sz < 0) {
sz = -sz;
is_atomic = TRUE; /* this block contains atomic objs */
} else {
is_atomic = FALSE;
}
if( sz > MAXOBJSZ ) { /* 1 big object */
mb = mark_bit(hbp, (hbp -> hb_body) - ((word *)(hbp)));
if (mb) {
(*fn)(client_data, (XR_Pointer)(hbp -> hb_body),
WORDS_TO_BYTES(sz), is_atomic);
}
} else { /* small objects */
p = (word *)(hbp->hb_body);
word_no = ((word *)p) - ((word *)hbp);
plim = (word *)((((unsigned)hbp) + HBLKSIZE)
- WORDS_TO_BYTES(sz));
while( p <= plim ) {
mb = mark_bit(hbp, word_no);
if (mb) {
(*fn)(client_data, (XR_Pointer)p,
WORDS_TO_BYTES(sz), is_atomic);
}
p += sz;
word_no += sz;
}
}
}
}
/* Call fn for each accessible object in the heap. All calls are perfomed */
/* with all threads not at GC priority stopped. This does a full, */
/* stop-the-world garbage collection before the first call to fn. */
/* The function fn must be prepared to run with the world stopped. It */
/* may not acquire monitor locks, since */
/* another thread may have been frozen while holding a lock. */
/* Fn is run on VP 0, and thus may use the UNIX stack for temporary */
/* storage if it chooses. */
void XR_EnumObjs(fn, client_data)
callback_fn fn;
XR_Pointer client_data;
{
RegisterGCCallbackType oldduring;
XR_Pointer oldclientdata;
struct CallBackInfoRep my_cbi;
XR_MonitorEntry(&GC_allocate_ml);
my_cbi.my_fn = fn;
my_cbi.my_client_data = client_data;
my_cbi.got_proper_callback = FALSE;
XR_RegisterGCCallBackDuringInner(callback,&my_cbi,
&oldduring,&oldclientdata);
while (!my_cbi.got_proper_callback) {
GC_demand_full_and_wait();
}
XR_RegisterGCCallBackDuringInner(oldduring,oldclientdata,0,0);
XR_MonitorExit(&GC_allocate_ml);
}